package principal;

/**
 * Javier Abell�n, 24 Mayo 2006.
 * Trazo que se dibuja en el paint.
 */

import java.awt.Color;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Trazo que se dibuja en el paint. Esta compuesto de muchos puntos que se unir�n por una l�nea de color.
 * @author  Chuidiang
 */
public class Trazo
{
	/**
	 * Color del trazo
	 * @uml.property  name="color"
	 */
    private Color color = Color.black;

    /**
	 * Devuelve el color del trazo
	 * @uml.property  name="color"
	 */
    public Color getColor()
    {
        return color;
    }
    
    public Trazo(){}

    /**
	 * Fija el color para el trazo
	 * @uml.property  name="color"
	 */
    public void setColor(Color color)
    {
        this.color = color;
    }

    /**
	 * Lista de puntos que compone el trazo
	 * @uml.property  name="puntos"
	 */
    private LinkedList<Point2D> puntos = new LinkedList<Point2D>();

    /** A�ade un nuevo punto al trazo */
    public void addPunto(Point2D punto)
    {
        puntos.add(punto);
    }

    /**
	 * Devuelve la lista de puntos que compone el trazo
	 * @uml.property  name="puntos"
	 */
    public LinkedList<Point2D> getPuntos()
    {
        return puntos;
    }

    /** Devuelve cu�ntos puntos componen el trazo */
    public int getNumeroPuntos()
    {
        return puntos.size();
    }

    /** A�ade un nuevo punto al trazo */
    public void addPunto(int x, int y)
    {
        Point2D p = new Point2D.Float(x, y);
        puntos.add(p);
    }

    /** Devuelve el punto de la lista en la posici�n indicada
     * 
     * @param posicion en la lista, entre 0 y getNumeroPuntos()-1
     * @return El punto
     */
    public Point2D getPunto(int posicion)
    {
        return puntos.get(posicion);
    }

    /**
     * Devuelve una pseudodistancia entre el punto x,y y el punto m�s cercano
     * del trazo.
     * M�todo �til para saber a qu� distancia del trazo se pincha el rat�n.
     * @param x de un punto exterior al trazo
     * @param y de un punto exterior al trazo.
     * @return La distancia
     */
    public double dameDistanciaMinima(int x, int y)
    {
        double distancia = dameDistancia(x, y, 0);
        for (int i = 1; i < puntos.size(); i++)
        {
            distancia = Math.min(dameDistancia(x, y, i), distancia);
        }
        return distancia;
    }

    /**
     * Devuelve la pseudo-distancia entre el punto x,y y el punto i de la lista.
     * @param x de un punto exterior al trazo
     * @param y de un punto exterior al trazo
     * @param i La posicion de un punto en la lista de puntos de este trazo
     * @return La pseuod-distancia entre x,y y el punto de posicion i
     */
    private double dameDistancia(int x, int y, int i)
    {
        return Math.abs(puntos.get(i).getX() - x)
                + Math.abs(puntos.get(i).getY() - y);
    }

		
		/**
		 */
		public Point2D getOrigen(){
			return puntos.getFirst();
		}
		
		public Point2D getInicioDibujo(){
			Point p = new Point();
			p.setLocation(get_punto_mas_izq(), get_punto_mas_alto());
			
			return p;
		}

			
			/**
			 */
			public int get_punto_mas_alto(){
				Iterator it = puntos.iterator();
				Point2D tmp;
				int ret = Integer.MAX_VALUE;
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getY()<ret)
						ret = (int)tmp.getY(); 
				}
				
				return ret;
			}
			
			public int get_punto_mas_bajo(){
				Iterator it = puntos.iterator();
				Point2D tmp;
				int ret = Integer.MIN_VALUE;
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getY()>ret)
						ret = (int)tmp.getY(); 
				}
				
				return ret;
			}
			
			public int get_punto_mas_izq(){
				Iterator it = puntos.iterator();
				Point2D tmp;
				int ret = Integer.MAX_VALUE;
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getX()<ret)
						ret = (int)tmp.getX(); 
				}
				
				
				return ret;
			}
			
			public int get_punto_mas_der(){
				Iterator it = puntos.iterator();
				Point2D tmp;
				int ret = Integer.MIN_VALUE;
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getX()>ret)
						ret = (int)tmp.getX(); 
				}
				
				return ret;
			}

			public int getAchura() {
				return get_punto_mas_der()-get_punto_mas_izq();
			}

			public int getAltura() {
				return get_punto_mas_bajo()-get_punto_mas_alto();
			}

			public List<Point2D> getPuntosArriba(Point centro) {
				// TODO Auto-generated method stub
				List<Point2D> res = new ArrayList<Point2D>();
				Iterator<Point2D> it = puntos.iterator();
				Point2D tmp;
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getY()<centro.getY())
						res.add(tmp);
				}
				return res;
			}
			
			public List<Point2D> getPuntosAbajo(Point centro) {
				// TODO Auto-generated method stub
				List<Point2D> res = new ArrayList<Point2D>();
				Iterator<Point2D> it = puntos.iterator();
				Point2D tmp;
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getY()>centro.getY())
						res.add(tmp);
				}
				return res;
			}
			
			public List<Point2D> getPuntosIzquierda(Point centro) {
				// TODO Auto-generated method stub
				List<Point2D> res = new ArrayList<Point2D>();
				Iterator<Point2D> it = puntos.iterator();
				Point2D tmp;
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getX()<centro.getX())
						res.add(tmp);
				}
				return res;
			}
			
			public List<Point2D> getPuntosDerecha(Point centro) {
				// TODO Auto-generated method stub
				List<Point2D> res = new ArrayList<Point2D>();
				Iterator<Point2D> it = puntos.iterator();
				Point2D tmp;
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getX()>centro.getX())
						res.add(tmp);
				}
				return res;
			}
			
			public Point2D getFin(){
				return puntos.getLast();
			}
			
			public Point getCentroMasa(){
				
				int coordX = (get_punto_mas_der()+get_punto_mas_izq())/2; 
				int coordY = (get_punto_mas_bajo()+get_punto_mas_alto())/2;
				Point res = new Point(coordX, coordY);
				
				return res;
				
			}
			
			public Point2D get_point_mas_bajo(){
				Iterator it = puntos.iterator();
				int max = Integer.MIN_VALUE;
				Point2D tmp;
				Point2D res = null;
				
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getY()>max){
						max = (int) tmp.getY();
						res = tmp;
					}
				}
				
				return res;
			}
			
			public Point2D get_point_mas_alto(){
				Iterator it = puntos.iterator();
				int min = Integer.MAX_VALUE;
				Point2D tmp;
				Point2D res = null;
				
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getY()<min){
						min = (int) tmp.getY();
						res = tmp;
					}
				}
				
				return res;
			}
			
			public Point2D get_point_mas_derecha(){
				Iterator it = puntos.iterator();
				int max = Integer.MIN_VALUE;
				Point2D tmp;
				Point2D res = null;
				
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getX()>max){
						max = (int) tmp.getX();
						res = tmp;
					}
				}
				
				return res;
			}
			
			public Point2D get_point_mas_izquierda(){
				Iterator it = puntos.iterator();
				int min = Integer.MAX_VALUE;
				Point2D tmp;
				Point2D res = null;
				
				while(it.hasNext()){
					tmp = (Point2D)it.next();
					if(tmp.getX()<min){
						min = (int) tmp.getX();
						res = tmp;
					}
				}
				
				return res;
			}

}
